package com.wsd.bookkeeping.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wsd.bookkeeping.entity.Record;
import com.wsd.bookkeeping.mapper.BillingMapper;
import com.wsd.bookkeeping.mapper.RecordMapper;
import com.wsd.bookkeeping.service.BillingService;
import com.wsd.bookkeeping.vo.BillingListVO;
import com.wsd.common.mapper.UserMapper;
import org.apache.tomcat.jni.Local;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class BillingServiceImpl implements BillingService {

    @Resource
    private BillingMapper billingMapper;
    @Resource
    private RecordMapper recordMapper;
    @Resource
    private UserMapper userMapper;

    @Override
    public Map<Integer, BillingListVO> queryBillingListByDate(Integer bookId, String year) {
        Map<Integer, BillingListVO> ansMap = new HashMap<>();
        List<BillingListVO> billingListVOS = billingMapper.queryBillingListByDate(bookId, year);

        for (BillingListVO vo : billingListVOS) {
            ansMap.put(vo.getMonth(), vo);
        }

        int month = LocalDate.now().getMonthValue();

        for (int i = 1; i <= month; i++) {
            if (ansMap.get(i) == null) {
                ansMap.put(i, BillingListVO.emptyEntity(i));
            }
        }

        return ansMap;
    }

    @Override
    public Map<String, Object> getBillListByMonthDate(Integer bookId, String date) throws InterruptedException {

        QueryWrapper<Record> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight("update_date", date);
        queryWrapper.eq("book_id", bookId);
        queryWrapper.orderByDesc("record_amount");
        queryWrapper.last("limit 0, 100");  // 前100条数据

        List<Record> records = recordMapper.selectList(queryWrapper);
        Map<String, Object> ansMap = new HashMap<>();

        // 根据支出，收入类型分组
        Map<String, List<Record>> collect = records.stream().collect(Collectors.groupingBy(Record::getRecordType));
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        CountDownLatch countDownLatch = new CountDownLatch(2);

        executorService.execute(() -> {
            // 收入
            List<Record> incomeList = collect.get("0");
            if (incomeList != null && incomeList.size() > 0) {
                Map<String, BigDecimal> incomeCollect = incomeList.stream().collect(Collectors.groupingBy(Record::getStyleName, Collectors.reducing(BigDecimal.ZERO, Record::getRecordAmount, BigDecimal::add)));
                ansMap.put("income", incomeCollect);

                // 人员收入
                Map<Integer, BigDecimal> userCollect = incomeList.stream().collect(Collectors.groupingBy(Record::getUserId, Collectors.reducing(BigDecimal.ZERO, Record::getRecordAmount, BigDecimal::add)));
                Set<Integer> userIdkeySet = userCollect.keySet();

                Map<Integer, String> userNameMapping = userMapper.getUserNicknameByIdList(userIdkeySet).stream().collect(Collectors.toMap(e -> Integer.valueOf(e.get("id").toString()), e -> e.get("nickname").toString()));
                Map<String, BigDecimal> userIncomeMapping = new HashMap<>();
                userCollect.forEach((k, v) -> {
                    userIncomeMapping.put(userNameMapping.get(k), v);
                });

                ansMap.put("userIncome", userIncomeMapping);
            }
            countDownLatch.countDown();
        });

        executorService.execute(() -> {
            // 支出
            List<Record> outcomeList = collect.get("1");
            if (outcomeList != null && outcomeList.size() > 0) {
                Map<String, BigDecimal> outcomeCollect = outcomeList.stream().collect(Collectors.groupingBy(Record::getStyleName, Collectors.reducing(BigDecimal.ZERO, Record::getRecordAmount, BigDecimal::add)));
                ansMap.put("outcome", outcomeCollect);

                // 人员支出
                Map<Integer, BigDecimal> userCollect = outcomeList.stream().collect(Collectors.groupingBy(Record::getUserId, Collectors.reducing(BigDecimal.ZERO, Record::getRecordAmount, BigDecimal::add)));
                Set<Integer> userIdkeySet = userCollect.keySet();

                Map<Integer, String> userNameMapping = userMapper.getUserNicknameByIdList(userIdkeySet).stream().collect(Collectors.toMap(e -> Integer.valueOf(e.get("id").toString()), e -> e.get("nickname").toString()));
                Map<String, BigDecimal> userOutcomeMapping = new HashMap<>();
                userCollect.forEach((k, v) -> {
                    userOutcomeMapping.put(userNameMapping.get(k), v);
                });

                ansMap.put("userOutcome", userOutcomeMapping);

            }
            countDownLatch.countDown();
        });
        countDownLatch.await();

        return ansMap;
    }
}
